package de.lmu.ifi.pst.uwejsf.framework;

import java.util.List;
import java.util.Map;

/**
 * This interface has to be implemented by custom persistence managers.
 * It defines methods to create, read, update and delete persistent objects (CRUD). 
 * The applications persistence manager is registered for the application by
 * specifying it's qualified class name in <code>uwe-config.xml</code> with
 * the tag <code>uwejsf/m2tConfig/persistenceManager</code>. The persistence manager
 * is then registered as a managed bean within the application scope and with the
 * identifier <code>persistenceManager</code>.
 * <p>
 * The load and query methods each use a parameter that contains the qualified
 * class name from the content model. {@link PersistenceManager} also declares
 * two methods to map the qualified class name from the UWE model 
 * (e.g. <code>content::Customer</code>) to the full qualified Java class name 
 * (e.g. <code>com.acme.webstore.model.Customer</code>) and vice-versa.   
 * </p>
 * 
 * 
 * @author Christian Kroiss
 * 
 */
public interface PersistenceManager {
	public static final String SCOPE_KEY = "persistenceManager";
	
	/**
	 * Loads a persistent object that is identified by the given key and
	 * qualified UWE model class name.
	 * 
	 * @param className the UWE model class name of the object to load.
	 * @param key the primary key value of the object to load.
	 * @return the loaded instance or null if no object matching the given key
	 * could be found.
	 */
	public Object loadByKey(String className, Object key);

	/**
	 * Creates an instance of the given class. 
	 * @param className the qualified UWE model class name
	 * @return a new instance of the given class.
	 * @throws UWEJSFRuntimeException if the instantiation fails.
	 */
	public Object createObject(String className);

	/**
	 * Executes a query using the given element class name, expression, 
	 * parameters and context provider. The name of the navigation node that defines
	 * the query is also given and could be used by custom implementations to
	 * decide on the concrete query mechanism.  
	 *  
	 * @param elementClassName the qualified UWE class name of the elements to query. 
	 * @param expression the query expression.
	 * @param navigationNode the navigation node that defines the query.
	 * @param parameters the parameters of the query.
	 * @param contextProvider the context provider.
	 * 
	 * @return the result list.
	 */
	public List<?> query(String elementClassName, String expression,
			String navigationNode, Map<String, Object> parameters,
			ExpressionContextProvider contextProvider);

	/**
	 * Executes a query using the default context provider. 
	 * See {@link #query(String, String, String, Map, ExpressionContextProvider)}.
	 */
	public List<?> query(String elementClassName, String expression,
			String navigationNode, Map<String, Object> parameters);


	/**
	 * Saves an object. If the object has not been persisted before, a
	 * new row is created. Otherwise an update is executed.
	 * 
	 * @param obj the object to save.
	 */
	public void saveObject(Object obj);
	
	
	/**
	 * Deletes a persistent object.
	 * @param obj the object to delete.
	 */
	public void deleteObject(Object obj);
	
	/**
	 * Maps a full qualified Java class name to it's corresponding UWE
	 * class name.
	 * 
	 * @param javaClassName the full qualified Java class name.
	 * @return the qualified UWE model class name.
	 */
	public String getModelQNameString(String javaClassName);

	
	/**
	 * Maps a qualified UWE class name a to it's corresponding 
	 * full qualified Java class name. 
	 * 
	 * @param the qualified UWE model class name.
	 * @return the full qualified Java class name.
	 */
	public Class<?> getApplicationClassByModelQName(String modelQName);

}
